<?php
// +----------------------------------------------------------------------
// | ManniuRead
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://manniuyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: heitao <read@manniuyun.com>
// +----------------------------------------------------------------------

namespace app\book\model;

use manniu\model\Base;

use app\member\model\Member;
use think\Cache;
use think\exception\HttpException;
use think\Log;

class BookBuy extends Base
{
    // 只读字段
    protected $readonly = ['uid', 'book_id', 'chapter_id', 'buy_price'];
    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = true;
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    // 已购买图书章节的缓存前缀
    protected $bookChapterBuyCachePrefix = 'book_chapter_buy_';

    // 模型事件
    protected static function init()
    {
        // 钩子 - 新增后
        BookBuy::afterInsert(function ($book_buy) {
            $book_buy->setBookChapterBoughtIdsCache($book_buy->getData('uid'), $book_buy->getData('book_id'));
        });

        // 钩子 - 删除前
        BookBuy::beforeDelete(function ($book_buy) {
            return false;
        });
    }

    public static function Buy($uid, $book_id, $chapter_id)
    {
        $member = Member::get($uid);
        if (!$member) {
            return false;
        }
        $chapter_price = (int)Chapter::where(['id' => $chapter_id, 'book_id' => $book_id])->value('price');
        if ($chapter_price === 0) {
            return true;
        } else if ($chapter_price < 0 || !is_numeric($chapter_price)) {
            Log::init([
                'type' => 'file',
                'level' => ['error']
            ]);
            Log::record('图书 ' . $book_id . ' 章节 ' . $chapter_id . ' 的价格异常,其值为：(' . $chapter_price . ')', 'error');
            throw new HttpException(404, '系统错误请联系管理员');
        } else if ($chapter_price > $member->read_money) {
            BookAutoSubscription::closeAutoSubscription($uid, $book_id);
            return false;
        } else if ($member->read_money > 0) {
            $member->read_money = $member->read_money - $chapter_price;
            $member->save();
            self::saveBuy([
                'uid' => $uid,
                'book_id' => $book_id,
                'chapter_id' => $chapter_id,
                'buy_price' => $chapter_price
            ]);
            return true;
        }
        return false;
    }

    public static function checkPaid($uid, $book_id, $chapter_id)
    {
        $result = self::where(['uid'=>$uid,'book_id'=>$book_id,'chapter_id'=>$chapter_id])->count();
        if($result){
            return true;
        }
        return false;
    }

    /**
     * 保存购买记录
     * @param $data array 购买信息
     * @return bool
     */
    public static function saveBuy($data = [])
    {
        /*
        if(!isset($data['uid']) || !isset($data['book_id']) || !isset($data['chapter_id']) || !$data['buy_price']){
            Log::init([
                'type' => 'file',
                'level' => ['error']
            ]);
            Log::record('参数错误', 'error');
            throw new HttpException(404, '系统错误请联系管理员');
        }
        */
        $result = self::create([
            'uid' => $data['uid'],
            'book_id' => $data['book_id'],
            'chapter_id' => $data['chapter_id'],
            'buy_price' => $data['buy_price']
        ]);
        if ($result) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取图书购买记录
     * @param int $uid 用户ID
     * @param int $book_id 图书ID
     * @return array
     */
    public function getBookBought($uid = 0, $book_id = 0, $cache = 300)
    {
        $uid = (int)$uid;
        $book_id = (int)$book_id;
        if (!$uid || !$book_id) {
            return [];
        }
        $book_buy = $this->getBookBoughtCache($uid, $book_id);
        if (!$book_buy) {
            $book_buy = $this->setBookChapterBoughtIdsCache($uid, $book_id, $cache, true);
        }
        $book_buy = $book_buy ? $book_buy : [];
        return $book_buy;
    }

    /**
     * 获取图书购买缓存记录
     * @param int $uid 用户ID
     * @param int $book_id 图书ID
     * @return mixed
     */
    protected function getBookBoughtCache($uid = 0, $book_id = 0)
    {
        return Cache::get($this->bookChapterBuyCachePrefix . 'u_' . $uid . 'b_' . $book_id);
    }

    /**
     * 删除图书购买缓存记录
     * @param int $uid 用户ID
     * @param int $book_id 图书ID
     * @return mixed
     */
    protected function rmBookBuyCache($uid = 0, $book_id = 0)
    {
        Cache::rm($this->bookChapterBuyCachePrefix . 'u_' . $uid . 'b_' . $book_id);
    }

    /**
     * 生成图书购买缓存记录
     * @param int $uid 用户ID
     * @param int $book_id 图书ID
     * @param bool $cache 缓存标识/缓存时间
     * @param bool $is_return 是否返回数据
     * @return array
     */
    protected function setBookChapterBoughtIdsCache($uid = 0, $book_id = 0, $cache = false, $is_return = false)
    {
        $book_buy = [];
        $data = $this->field('chapter_id')->where(['uid' => $uid, 'book_id' => $book_id])->cache($cache)->select();
        if ($data) {
            foreach ($data as $item) {
                $book_buy[] = $item->getdata('chapter_id');
            }
            Cache::set($this->bookChapterBuyCachePrefix . 'u_' . $uid . 'b_' . $book_id, $book_buy);
        }
        if ($is_return === true) {
            $book_buy = $book_buy ? $book_buy : [];
            return $book_buy;
        }
    }

    /**
     * 生成用户的所有图书购买缓存记录
     * @param int $uid
     */
    protected function setBookChapterBoughtIdsByUid($uid = 0)
    {
        $book_ids = [];
        $data = $this->distinct(true)->field('book_id')->where(['uid' => $uid])->select();
        if ($data) {
            foreach ($data as $item) {
                $book_ids[] = $item->getData('book_id');
            }
        }
        foreach ($book_ids as $item) {
            $this->setBookChapterBoughtIdsCache($uid, (int)$item);
        }
    }
}